package com.honghe.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.honghe.constant.MessageConstant;
import com.honghe.constant.PasswordConstant;
import com.honghe.context.BaseContext;
import com.honghe.dto.*;
import com.honghe.entity.DocPat;
import com.honghe.entity.Doctor;
import com.honghe.entity.DoctorPatient;
import com.honghe.exception.BaseException;
import com.honghe.exception.LoginFailedException;
import com.honghe.exception.PasswordEditFailedException;
import com.honghe.exception.PasswordErrorException;
import com.honghe.mapper.DepartmentMapper;
import com.honghe.mapper.DocPatMapper;
import com.honghe.mapper.DoctorMapper;
import com.honghe.result.PageResult;
import com.honghe.service.DoctorService;
import com.honghe.vo.DocVisitVO;
import com.honghe.vo.DoctorPageVO;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;

@Service
public class DoctorServiceImpl implements DoctorService {
    @Autowired
    private DepartmentMapper departmentMapper;
    @Autowired
    private DoctorMapper doctorMapper;
    @Autowired
    private DocPatMapper docPatMapper;

    @Override
    public Doctor login(DoctorLoginDTO doctorLoginDTO) {
        String username = doctorLoginDTO.getUsername();
        String password = doctorLoginDTO.getPassword();
        Doctor doctor = doctorMapper.getByUsername(username);
        if (doctor == null) {
            throw new LoginFailedException(MessageConstant.ACCOUNT_NOT_FOUND);
        }
        //对密码进行md5加密
        password = DigestUtils.md5DigestAsHex(password.getBytes());
        //对加密后的密码进行比对
        if (!password.equals(doctor.getPassword())) {
            throw new LoginFailedException(MessageConstant.PASSWORD_ERROR);
        }
        return doctor;
    }

    @Override
    public PageResult pageQuery(DoctorPageDTO doctorPageDTO) {
        PageHelper.startPage(doctorPageDTO.getPage(), doctorPageDTO.getPageSize());
        Page<DoctorPageVO> page = doctorMapper.page(doctorPageDTO);
        PageResult pageResult = new PageResult();
        pageResult.setTotal(page.getTotal());
        if (page.getResult() == null || page.getResult().isEmpty()) {
            PageHelper.startPage(1, doctorPageDTO.getPageSize());
            page = doctorMapper.page(doctorPageDTO);
            pageResult.setRecords(page.getResult());
            return pageResult;
        }
        pageResult.setRecords(page.getResult());
        return pageResult;
    }

    @Override
    public void insert(DoctorDTO doctorDTO) {
        if (!doctorDTO.getPhone().matches("1[3-9]\\d{9}")) {
            throw new BaseException("手机号不合法");
        }
        Doctor doctor = new Doctor();
        BeanUtils.copyProperties(doctorDTO, doctor);
        doctor.setPassword(PasswordConstant.DEFAULT_PASSWORD);
        doctor.setUsername(randomUsername());
        doctorMapper.insert(doctor);
    }

    @Override
    public void update(DoctorDTO doctorDTO) {
        if (!doctorDTO.getPhone().matches("1[3-9]\\d{9}")) {
            throw new BaseException("手机号不合法");
        }
        Doctor doctor = new Doctor();
        BeanUtils.copyProperties(doctorDTO, doctor);
        doctorMapper.update(doctor);
    }

    @Override
    public void delete(Long id) {
        doctorMapper.deleteById(id);
    }

    @Override
    public Doctor getById(Long id) {
        Doctor doctor = doctorMapper.getById(id);
        return doctor;
    }

    @Override
    public void changePassword(DoctorPasswordDTO doctorPasswordDTO) {
        Doctor doctor = doctorMapper.getByUsername(doctorPasswordDTO.getUsername());
        if (doctor == null) {//查询是否有该账号
            throw new LoginFailedException(MessageConstant.ACCOUNT_NOT_FOUND);
        }
        String oldPassword = doctorPasswordDTO.getOldPassword();
        oldPassword = DigestUtils.md5DigestAsHex(oldPassword.getBytes());
        if (!oldPassword.equals(doctor.getPassword())) {
            throw new PasswordErrorException("旧" + MessageConstant.PASSWORD_ERROR);
        }
        String newPassword = doctorPasswordDTO.getNewPassword();
        newPassword = DigestUtils.md5DigestAsHex(newPassword.getBytes());
        Long id = doctor.getId();
        doctorMapper.updatePassword(id, newPassword);
    }

    @Override
    public DocVisitVO getPatByDate(LocalDate date) {
        DocVisitVO docVisitVO = new DocVisitVO();
        //获取医生id
        Long docId = BaseContext.getCurrentId();
        //通过医生id和日期获取病人数据
        Map<String, Object> map = new HashMap<>();
        map.put("docId", docId);
        map.put("begin", LocalDateTime.of(
                date, LocalTime.MIN
        ));
        map.put("end", LocalDateTime.of(
                date, LocalTime.MAX
        ));
        List<DocPat> docPats = docPatMapper.getByMap(map);
        docVisitVO.setVisitDate(date);
        docVisitVO.setDoctorPatientList(docPats);
        return docVisitVO;
    }

    @Override
    public void updateStatus(DocUpdateStatusDTO docUpdateStatusDTO) {
        Long docId = BaseContext.getCurrentId();
        DoctorPatient docPat = docPatMapper.getById(docUpdateStatusDTO.getVisitId());
        if (!Objects.equals(docPat.getDoctorId(), docId)){
            throw new BaseException(MessageConstant.UPDATE_STATUS_ERROR);
        }
        LocalDate visitTime = docPat.getVisitTime().toLocalDate();
        LocalDate today = LocalDate.now();
        if (today.equals(visitTime)) {
            docPatMapper.updateStatus(docUpdateStatusDTO.getVisitId(), docUpdateStatusDTO.getStatus());
        }else {
            throw new BaseException(MessageConstant.UPDATE_STATUS_ERROR);
        }
    }

    @Override
    public void importExcel(String filePath) {
        try (InputStream inputStream = new FileInputStream(filePath)) {
            XSSFWorkbook excel = new XSSFWorkbook(inputStream);
            XSSFSheet sheet = excel.getSheetAt(0);//获取第一个表
            int lastSheet = sheet.getLastRowNum();//获取最后一行
            for (int i = 2; i <= lastSheet; i++) {
                XSSFRow row = sheet.getRow(i);//获取每行数据
                String name = row.getCell(0).getStringCellValue();
                String sex = row.getCell(1).getStringCellValue();
                Integer age = (int) row.getCell(2).getNumericCellValue();//将字符串类型的数字转化为int类型
                long numericCellValue = (long) row.getCell(3).getNumericCellValue();
                String phone = String.valueOf(numericCellValue);
                String deptName = row.getCell(4).getStringCellValue();
                Integer job = (int) row.getCell(5).getNumericCellValue();
                Integer deptId = departmentMapper.getIdByName(deptName);
                DoctorDTO doctorDTO = new DoctorDTO(
                        null,
                        name, sex.equals("男") ? 1 : 2, age,
                        phone, deptId, job
                );
                insert(doctorDTO);
            }
            excel.close();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 随机生成用户名
     */
    public String randomUsername() {
        String uuid = UUID.randomUUID().toString();
        int i = uuid.lastIndexOf("-");
        uuid = uuid.substring(i + 1);
        return uuid;
    }
}
